home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / sunprom / fsDisk.h < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-08  |  17.4 KB  |  420 lines

  1. /*
  2.  * fsDisk.h --
  3.  *
  4.  *    Definitions related to the storage of a filesystem on a disk.
  5.  *
  6.  * Copyright 1986 Regents of the University of California
  7.  * All rights reserved.
  8.  *
  9.  *
  10.  * $Header: /sprite/src/kernel/fs/RCS/fsDisk.h,v 8.3 89/03/08 12:48:15 jhh Exp $ SPRITE (Berkeley)
  11.  */
  12.  
  13. #ifndef _FSDISK
  14. #define _FSDISK
  15.  
  16. #include "dev.h"
  17.  
  18. /*
  19.  * A disk is partitioned into domains that are managed separately.
  20.  * Each domain takes up an even number of cylinders.
  21.  * An array of FsDiskPartition's is kept on the disk to define how the
  22.  * disk is divided into domains.
  23.  *
  24.  * FS_NUM_DISK_PARTS defines how many different domains there could be
  25.  *    on a disk.  Generally, not all the domains are defined.  
  26.  */
  27. #define FS_NUM_DISK_PARTS    8
  28.  
  29. typedef struct FsDiskPartition {
  30.     int firstCylinder;    /* The first cylinder in the partition. */
  31.     int numCylinders;    /* The number of cylinders in the partition.  Set
  32.              * this to zero for unused partitions. */
  33. } FsDiskPartition;
  34.  
  35. /*
  36.  * The first few blocks of each domain are reserved.  They contain a copy
  37.  * of the Disk Header, a copy of the boot program, and finally Domain
  38.  * Header information.  The Disk Header defines the division of the disk's
  39.  * cylinders into domains,  and the layout of the rest of the reserved
  40.  * blocks.  The Disk Header is replicated on the zero'th sector of each
  41.  * domain. For the Sun implementation, the boot program is expected to
  42.  * start in sector #1 and contain at most 15 sectors.  The boot program on
  43.  * the zero'th cylinder of the disk is used automatically, although other
  44.  * boot program locations can be specified manually.
  45.  *
  46.  *      NOTE: we are temporarily using Sun's format of the Disk Header,
  47.  *      not the following typedef.  Sun's label is defined in
  48.  *      "../sun/sunDiskLabel.h".  We assume that sector zero contains a
  49.  *      Sun format label, sectors 1 through 16 contain a boot program.
  50.  *      Sector SUN_SUMMARY_SECTOR contains an FsSummaryInfo structure.
  51.  *      Sector SUN_DOMAIN_SECTOR contains an FsDomainHeader structure.
  52.  */
  53.  
  54. typedef struct FsDiskHeader {
  55.     char asciiLabel[128];    /* Human readable string used for manufacturer's
  56.                  * model number and redudant geometry info */
  57.     /*
  58.      * Padding is used to shove the following data down so the check sum
  59.      * occurs at the end of the sector.  The 10 in the declaration indicates
  60.      * how may integer fields there are in this struct.
  61.      */
  62.     char pad[DEV_BYTES_PER_SECTOR - 128 -
  63.          (12 + FS_NUM_DISK_PARTS * 2) * sizeof(int)];
  64.     unsigned int magic;        /* Magic number used for consistency check */
  65.     int numCylinders;        /* The number of cylinders on the disk */
  66.     int numAltCylinders;    /* # of alternates used for bad blocks */
  67.     int numHeads;        /* # of surfaces on the disk */
  68.     int numSectors;        /* # of sectors per track */
  69.     int bootSector;        /* The starting sector of the boot program.
  70.                  * This is usually 1. */
  71.     int numBootSectors;        /* The number of sectors in the boot program.
  72.                  * This is usually 15. */
  73.     int summarySector;        /* Index of sector used for summary info */
  74.     int domainSector;        /* The sector where the domain header starts.*/
  75.     int numDomainSectors;    /* The number of sectors taken up by the
  76.                  * domain header */
  77.     int partition;        /* Index of the partition that this copy of
  78.                  * the Disk Header is on.  Each partition has
  79.                  * a copy of the Disk Header */
  80.     FsDiskPartition map[FS_NUM_DISK_PARTS];    /* Partition map */
  81.     int checkSum;        /* Checksum such that an XOR of all the ints
  82.                  * in the sector results in the same thing
  83.                  * as the magic number */
  84. } FsDiskHeader;
  85.  
  86. #define FS_DISK_MAGIC    (unsigned int)0xD15CFEBA    /* 'disk fever' */
  87.  
  88.  
  89.  
  90. /*
  91.  * The geometry of a disk is a parameter to the disk block allocation routine.
  92.  * It is stored in disk in the Domain header so that different configurations
  93.  * on the same disk can be tried out and compared.
  94.  *
  95.  * The following parameters define array sizes in the FsGeometry struct.
  96.  *
  97.  * FS_MAX_ROT_POSITIONS defines how many different rotational positions are
  98.  * possible for a filesystem block.  An Eagle Drive, for example, has 23
  99.  * rotational positions.  There are 46 sectors per track.  That means that
  100.  * 5 4K filesystem blocks fit on a track and the 6th spills over onto the
  101.  * next track.  This offsets all the 4K blocks on the next track by 1K.
  102.  * This continues for 4 tracks after which 23 whole blocks have been
  103.  * packed in.  The set of 23 blocks is called a ``rotational set''.
  104.  * Also, because the Eagle has 20 heads, and each rotational set occupies
  105.  * 4 tracks, there are 5 rotational sets per cylinder.
  106.  *
  107.  * FS_MAX_TRACKS_PER_SET defines how many tracks a rotational set can
  108.  * take up.
  109.  */
  110. #define FS_MAX_ROT_POSITIONS    32
  111. #define FS_MAX_TRACKS_PER_SET    10
  112.  
  113. typedef struct FsGeometry {
  114.     /*
  115.      * Fundamental disk geometry that cannot be varied.
  116.      */
  117.     int        sectorsPerTrack;/* The number of sectors per track */
  118.     int        numHeads;    /* The number of surfaces on the disk */
  119.     /*
  120.      * Filesystem blocks take up several disk sectors, and filesystem
  121.      * blocks on different surfaces may be skewed relative to each other
  122.      * because a whole number of filesystem blocks generally does not fit
  123.      * on one track.  (This property is exploited when looking for blocks
  124.      * that are rotationaly optimal with respect to each other.)  The
  125.      * skewing pattern is repeated after a certain number of filesystem
  126.      * blocks.  The pattern is contrained to fit on a whole number of
  127.      * tracks, and a whole number of the patterns has to fit in one
  128.      * cylinder.  This means that there may be unused sectors at the end
  129.      * of each set of filesystem blocks.
  130.      */
  131.     int        blocksPerRotSet;    /* The number of distinct rotational
  132.                      * positions for filesystem blocks */
  133.     int        tracksPerRotSet;    /* The number of disk tracks taken
  134.                      * up by a rotational set.  Used to
  135.                      * bounce from one set to another
  136.                      * and to map from filesystem block
  137.                      * indexes to disk sectors */
  138.     int        rotSetsPerCyl;        /* The number of rotational sets in a
  139.                      * cylinder.  There are numRotPositions
  140.                      * filesystem blocks in each set */
  141.     int        blocksPerCylinder;    /* This is the product of blocksPerSet
  142.                      * and numRotationSets */
  143.     /*
  144.      * The following diagram shows a rotational set for a disk with 46
  145.      * 512 byte sectors per track.  8 disk sectors are needed for each
  146.      * filesystem block, and this allows 5 3/4 blocks per trask.
  147.      * This means that 23 filesystem blocks make up a rotational set
  148.      * that occupies 4 tracks.
  149.     ----------------------------------------------------
  150.     |..1.....|..2.....|..3.....|..4.....|..5.....|..6...    track 1
  151.     ----------------------------------------------------
  152.     ..|..7.....|..8.....|..9.....|..10....|..11....|..12    track 2
  153.     ----------------------------------------------------
  154.     ....|..13....|..14....|..15....|..16....|..17....|..    track 3
  155.     ----------------------------------------------------
  156.     .18...|..19....|..20....|..21....|..22....|..23....|    track 4
  157.     ----------------------------------------------------
  158.      * In order to facilitate rotationally optimal allocation the
  159.      * rotational positions are sorted by increasing offset.  In the
  160.      * above example, the sorted ordering is (1, 7, 13, 19, 2, 8...)
  161.      */
  162.     int        blockOffset[FS_MAX_ROT_POSITIONS];    /* This keeps the
  163.                      * starting sector number for each
  164.                      * rotational position.  This table
  165.                      * is computed by the makeFilesystem
  166.                      * user program */
  167.     int        sortedOffsets[FS_MAX_ROT_POSITIONS];    /* An ordered set of
  168.                      * the rotational positions */
  169.     /*
  170.      * Add more data after here so we have to reformat the disk less often.
  171.      */
  172. } FsGeometry;
  173.  
  174. /*
  175.  * A disk is partitioned into areas that each store a domain.  Each domain
  176.  * contains a DomainHeader that describes how the blocks of the domain are
  177.  * used.  The layout information takes into account the blocks that are
  178.  * reserved for the copy of the Disk Header and the boot program.
  179.  */
  180. typedef struct FsDomainHeader {
  181.     unsigned int magic;        /* magic number for consistency check */
  182.     int        firstCylinder;    /* Disk relative number of the first cylinder
  183.                  * in the domain.  This is redundant with
  184.                  * respect to the complete partition map
  185.                  * kept in the Disk Header */
  186.     int        numCylinders;    /* The number of cylinders in the domain.
  187.                  * Also redundant with Disk Header */
  188.     Fs_Device    device;        /* Device identifier of the domain passed to
  189.                  * the device driver block IO routines.
  190.                  * Two fields are valid on disk: the serverID
  191.                  * records the rpc_SpriteID of the server,
  192.                  * and the unit number indicates which partition
  193.                  * in the superblock this header corresponds
  194.                  * to.  This is needed because more than one
  195.                  * partition can start at the same spot on
  196.                  * disk (of course, only one is valid to use).
  197.                  * The device type on disk is ignored */
  198.     /*
  199.      * An array of FsDescriptors is kept on the disk and an accompanying
  200.      * bitmap is used to keep track of free and allocated file descriptors.
  201.      */
  202.     int        fdBitmapOffset;    /* The block offset of the bitmap used to
  203.                  * keep track of free FileDescriptors */
  204.     int        fdBitmapBlocks;    /* The number of blocks in the bitmap */
  205.     int        fileDescOffset;    /* The block offset of the array of fds.
  206.                  * The number of blocks in the array comes
  207.                  * from numFileDesc */
  208.     int        numFileDesc;    /* The number of FsDescriptors in the domain.
  209.                  * This is an upper limit on the number of
  210.                  * files that be kept in the domain */ 
  211.     /*
  212.      * A large bitmap is used to record the status of all the data blocks
  213.      * in the domain.
  214.      */
  215.     int        bitmapOffset;    /* The block number of the start of bitmap */
  216.     int        bitmapBlocks;    /* Number of blocks used to store bitmap */
  217.     /*
  218.      * The data blocks take up the rest of the domain.
  219.      */
  220.     int        dataOffset;    /* The block number of the start of data */
  221.     int        dataBlocks;    /* Number of data blocks */
  222.     int        dataCylinders;    /* Number of cylinders containing data blocks */
  223.     /*
  224.      * Disk geometery parameters are used map from block indexes to
  225.      * disk sectors, and also to optimally allocate blocks.
  226.      */
  227.     FsGeometry    geometry;    /* Used by the allocation routines and
  228.                  * by the block IO routines */
  229. } FsDomainHeader;
  230.  
  231. #define FS_DOMAIN_MAGIC    (unsigned int)0xF8E7D6C5
  232.  
  233. /*
  234.  * FS_NUM_DOMAIN_SECTORS is the standard number of sectors taken
  235.  * up by the domain header.
  236.  */
  237. #define FS_NUM_DOMAIN_SECTORS    ((sizeof(FsDomainHeader)-1) / DEV_BYTES_PER_SECTOR + 1)
  238.  
  239.  
  240. /*
  241.  * ONE sector of summary information is kept on disk.  This records things
  242.  * like the number of free blocks and free file descriptors.  This info
  243.  * is located just before the domain header.
  244.  */
  245. typedef struct FsSummaryInfo {
  246.     int        numFreeKbytes;        /* Free space in kbytes, not blocks */
  247.     int        numFreeFileDesc;    /* Number of free file descriptors */
  248.     int        state;            /* Unused. */
  249.     char    domainPrefix[64];    /* Last prefix used for the domain */
  250.     int        domainNumber;        /* The domain number of the domain
  251.                      * under which this file system was
  252.                      * last mounted. */
  253.     int        flags;            /* Flags defined below. */
  254.     int        attachSeconds;        /* Time the disk was attached */
  255.     int        detachSeconds;        /* Time the disk was off-lined.  This
  256.                      * is the fsTimeInSeconds that the
  257.                      * system was shutdown or the disk
  258.                      * was detached.  If the domain is
  259.                      * marked NOT_SAFE then this field
  260.                      * is undefined, but attachTime is ok
  261.                      * as long as TIMES_VALID is set. */
  262.     int        fixCount;        /* Number of consecutive times that 
  263.                      * fscheck has found an error in this
  264.                      * domain. Used to prevent infinite
  265.                      * looping.
  266.                      */
  267.  
  268. } FsSummaryInfo;
  269.  
  270. /*
  271.  * Flags for summary info structure.
  272.  *    FS_DOMAIN_NOT_SAFE    Set during normal operation. This is unset
  273.  *        when we know we    are shutting down cleanly and the data
  274.  *        structures on the disk partition (domain) are ok.
  275.  *    FS_DOMAIN_ATTACHED_CLEAN    Set if the initial attach found the
  276.  *        disk marked 'safe'
  277.  *    FS_DOMAIN_TIMES_VALID    If set then the attach/detachSeconds fields
  278.  *        are valid.
  279.  */
  280. #define    FS_DOMAIN_NOT_SAFE        0x1
  281. #define FS_DOMAIN_ATTACHED_CLEAN    0x2
  282. #define    FS_DOMAIN_TIMES_VALID        0x4
  283.  
  284.  
  285. /*
  286.  * A File Descriptor is kept on disk for every file in a domain.  It
  287.  * contains administrative information and also the indexing structure
  288.  * used to access the file's data blocks.
  289.  */
  290.  
  291. #define FS_NUM_DIRECT_BLOCKS    10
  292. #define FS_NUM_INDIRECT_BLOCKS    3
  293. #define    FS_INDICES_PER_BLOCK    1024
  294.  
  295. #define FS_MAX_FILE_DESC_SIZE    128
  296. #define FS_FILE_DESC_PER_BLOCK    (FS_BLOCK_SIZE / FS_MAX_FILE_DESC_SIZE)
  297.  
  298. typedef struct FsFileDescriptor {
  299.     unsigned short magic;/* FS_FD_MAGIC, for disk consistency check */
  300.     short flags;    /* FS_FD_FREE, FS_FD_ALLOC, FS_FD_RESERVED */
  301.     short fileType;    /* FS_REGULAR, FS_DIRECTORY, FS_PIPE, FS_DEVICE,
  302.              * FS_SYMLINK, FS_RMTLINK */
  303.     short permissions;    /* 9 permission bits plus flags for set user ID
  304.              * upon execution */
  305.     int uid;        /* ID of owner */
  306.     int gid;        /* Group ID of owner */
  307.     int lastByte;    /* The number of bytes in the file */
  308.     int lastByteXtra;    /* (Some day we may have 64 bit sizes?) */
  309.     int firstByte;    /* For named pipes, offset of the first valid byte */
  310.     int userType;    /* Information about what sort of user file it is. */
  311.     int numLinks;    /* Number of directory references to the file */
  312.     int devServerID;    /* ID of the host that controls the device */
  313.     short devType;    /* For devices, their type.  For others this is the
  314.              * type of disk the file is stored on */
  315.     unsigned short devUnit;    /* For devices, their unit number.  For others,
  316.              * the unit indicates the disk partition */
  317.     /*
  318.      * All times in seconds since Jan 1 1970, Greenwich time.
  319.      */
  320.  
  321.     int createTime;    /* Time the file was created. */
  322.     int accessTime;    /* Time of last access.  This is not updated by
  323.              * directory traversals. */
  324.     int descModifyTime;    /* Time of last modification to the file descriptor */
  325.     int dataModifyTime;    /* Time of last modification to the file data */
  326.  
  327.     /*
  328.      * Pointers to the data blocks of the file.   The pointers are really
  329.      * indexes into the array of blocks stored in the data block section
  330.      * of a partition.  The direct array contains the indexes of the first
  331.      * several blocks of the files.  The indirect indexes are interpreted
  332.      * as follows.  The first indirect index is the index of a block that
  333.      * contains 1 K indexes of data blocks.  This is called a singly-indirect
  334.      * block.  The second indirect index is the index of a block that
  335.      * contains 1 K indexes of singly-indirect blocks.  This is called
  336.      * a doubly-indirect block.  Finally, the third indirect index is the index
  337.      * of a block that contains 1 K indexes of doubly-indirect blocks.
  338.      * Each data block contains 4Kbytes, so this indexing scheme supports
  339.      * files up to 40K + 4Meg + 4Gig + 4Pig bytes.
  340.      *
  341.      * The values of the direct and indirect indexes are indexes of
  342.      * fragments, ie. 1k pieces.  All the but the last index point to the
  343.      * beginning of a filesystem block, ie. 4K.  The last valid direct
  344.      * block may point to a fragment, and fragments can start on 1K
  345.      * boundaries.
  346.      */
  347.  
  348.     int direct[FS_NUM_DIRECT_BLOCKS];
  349.     int indirect[FS_NUM_INDIRECT_BLOCKS];
  350.     int numKbytes;    /* The number of KiloBytes acutally allocated towards
  351.              * the file on disk.  This accounts for fragments
  352.              * and indirect blocks. */
  353.     int version;    /* Version number of the handle for the file.  Needed
  354.              * on disk for recovery purposes (client re-open */
  355. } FsFileDescriptor;
  356.  
  357. /*
  358.  * Magic number and flag definitions for file descriptors.
  359.  *    FS_FD_FREE    The file descriptor is unused
  360.  *    FS_FD_ALLOC    The file descriptor is used for a file.
  361.  *    FS_FD_RESERVED    The file descriptor is reserved and not for use.
  362.  *    FS_FD_DIRTY    The file descriptor has been modified since the
  363.  *            last time that it was written to disk.
  364.  */
  365. #define FS_FD_MAGIC    (unsigned short)0xF1D0
  366. #define FS_FD_FREE    0x1
  367. #define FS_FD_ALLOC    0x2
  368. #define FS_FD_RESERVED    0x4
  369. #define FS_FD_DIRTY    0x8
  370.  
  371. /*
  372.  * The special index value FS_NIL_INDEX for direct[] and indirect[]
  373.  * means there is no block allocated for that index.
  374.  */ 
  375. #define FS_NIL_INDEX    -1
  376. /*
  377.  * The bad block file, the root directory of a domain and the lost and found 
  378.  * directory have well known file numbers.
  379.  */
  380. #define FS_BAD_BLOCK_FILE_NUMBER    1
  381. #define FS_ROOT_FILE_NUMBER        2
  382. #define FS_LOST_FOUND_FILE_NUMBER    3
  383. /*
  384.  * The lost and found directory is preallocated and is of a fixed size. Define
  385.  * its size in 4K blocks here.
  386.  */
  387. #define    FS_NUM_LOST_FOUND_BLOCKS    2
  388.  
  389. /*
  390.  * A directory entry:
  391.  */
  392. typedef struct FsDirEntry {
  393.     int fileNumber;        /* Index of the file descriptor for the file. */
  394.     short recordLength;        /* How many bytes this directory entry is */
  395.     short nameLength;        /* The length of the name in bytes */
  396.     char fileName[FS_MAX_NAME_LENGTH+1];    /* The name itself */
  397. } FsDirEntry;
  398. /*
  399.  *    FS_DIR_BLOCK_SIZE    Directory's grow in multiples of this constant,
  400.  *        and records within a directory don't cross directory blocks.
  401.  *    FS_DIR_ENTRY_HEADER    The size of the header of a FsDirEntry;
  402.  *    FS_REC_LEN_GRAIN    The number of bytes in a directory record
  403.  *                are rounded up to a multiple of this constant.
  404.  */
  405. #define FS_DIR_BLOCK_SIZE    512
  406. #define FS_DIR_ENTRY_HEADER    (sizeof(int) + 2 * sizeof(short))
  407. #define FS_REC_LEN_GRAIN    4
  408.  
  409. /*
  410.  * FsDirRecLength --
  411.  *    This computes the number of bytes needed for a directory entry.
  412.  *    The argument should be the return of the String_Length function,
  413.  *    ie, not include the terminating null in the count.
  414.  */
  415. #define FsDirRecLength(stringLength) \
  416.     (FS_DIR_ENTRY_HEADER + \
  417.     ((stringLength / FS_REC_LEN_GRAIN) + 1) * FS_REC_LEN_GRAIN)
  418.  
  419. #endif _FSDISK
  420.